﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Net.Http;
using System.Threading;
using Common.Logging;
using In.Api.Dto.HisWs;
using Newtonsoft.Json;
using OutDbContext;
using Rmq.Center;
using User.Api.BizExtensions;
using User.Api.Helpers;
using User.Api.HttpClients;

namespace Out.TaskRunner.RmqWorkers
{
    public class OrderPickupingChkWorker : IWorker
    {
        private static readonly ILog Logger = LogManager.GetLogger(typeof(OrderPickupingChkWorker));

        public void Start(CancellationToken ct)
        {
            if (ct.IsCancellationRequested)
            {
                return;
            }

            using (var consumer = new OrderPickupingChkConsumer())
            {
                consumer.Subscribe((id, count, dt, msg, channel) =>
                {
                    if (msg.OrderType == OrderType.挂号订单)
                    {
                        return ProcessRegOrder(msg.OrderId, channel);
                    }
                    else if (msg.OrderType == OrderType.门诊缴费订单)
                    {
                        return ProcessBillOrder(msg.OrderId, channel);
                    }
                  

                    return new ConsumedResult { Ack = true };
                });

                while (true)
                {
                    if (ct.IsCancellationRequested)
                    {
                        break;
                    }

                    Thread.Sleep(500);
                }
            }
        }

        private ConsumedResult ProcessRegOrder(int orderId, WrapperChannel channel)
        {
            OrderSummary order;
            using (var ctx = new HzfyWeiXinEntities())
            {
                order = ctx.ApptOrder.Where(x => x.Id == orderId).Select(x => new OrderSummary
                {
                    OrderNo = x.OrderNo,
                    OrderType = x.OrderType,
                    Id = x.Id,
                    SumFee = x.SumFee,
                    WxUserId = x.WxUserId,
                    WxTransactionId = x.WxTransactionId,
                    RegDate = x.RegDate,
                    StartTime = x.StartTime,
                    EndTime = x.EndTime,
                    DeptName = x.DeptName,
                    DoctorName = x.DoctorName,
                    CardNo = x.CardNo,
                }).FirstOrDefault();

                if (order == null)
                {
                    return new ConsumedResult
                    {
                        Ack = true
                    };
                }
            }

            //执行查询挂号状态操作
            var regChkRequest = new Request4GetOrderStatus();
                regChkRequest.OrderId = order.OrderNo;

                Response4GetOrderStatus regChkResponse;
                try
                {
                    var httpClient = InHttpClient.GetClient();
                    var responseMsg = httpClient.PostAsJsonAsync("HisNewWs/GetRegOrderStatus", regChkRequest).Result;
                    responseMsg.EnsureSuccessStatusCode();
                    regChkResponse = responseMsg.Content.ReadAsAsync<Response4GetOrderStatus>().Result;
                }
                catch (Exception ex)
                {
                    Logger.ErrorFormat("查询挂号订单状态出错,信息：{0}", JsonConvert.SerializeObject(ex));

                    return new ConsumedResult
                    {
                        Ack = false,
                        Delay = 60*1000
                    };
                }

                //if (regChkResponse.ResultCode != "0")
                if(regChkResponse.ResultCode == "1" && regChkResponse.ResultDesc.Contains("未查询到订单挂号信息"))
                {

                    // 取号失败
                    //order.OrderStatus = ApptOrderExtensions.OrderStatus.取号失败.ToInt32();
                    //ctx.SaveChanges();
                    using (var _ctx = new HzfyWeiXinEntities())
                    {
                        SqlParameter[] para =
                            {
                    new SqlParameter("@OrderStatus", ApptOrderExtensions.OrderStatus.取号失败.ToInt32()),
                    new SqlParameter("@OrderId", order.Id),
                     };
                        _ctx.Database.ExecuteSqlCommand(
                            "Update ApptOrder set OrderStatus= @OrderStatus where Id=@OrderId", para);
                    }

                    if (order.OrderType == ApptOrderExtensions.OrderType.预约.ToInt32().ToString())
                    {
                    // RMQ 取消预约 
                    //var unapptingProducer = new OrderUnapptingProducer();
                    //unapptingProducer.Publish(new OrderUnapptingMsg
                    //{
                    //    OrderType = Rmq.Center.OrderType.挂号订单,
                    //    OrderId = order.Id,
                    //    Reason = 2
                    //});

                    // RMQ 执行取消锁号操作
                    var unlockingProducer = new OrderUnlockingProducer();
                    unlockingProducer.Publish(new OrderUnlockingMsg
                    {
                        OrderType = OrderType.挂号订单,
                        OrderId = orderId
                    });
                }

                    // RMQ 发送用户挂号失败通知
                    var msgProducer = new UserMessageProducer();
                    msgProducer.Publish(new UserMessageMsg
                    {
                        Type = UserMessageType.挂号失败通知,
                        OrderId = order.Id
                    });

                    // RMQ 执行退费操作
                    if (order.SumFee > 0)
                    {
                        var refundingProducer = new OrderRefundingPickupFailedProducer();
                        refundingProducer.Publish(new OrderRefundingPickupFailedMsg
                        {
                            OrderType = OrderType.挂号订单,
                            OrderId = order.Id
                        });
                    }
                }
                else
                {
                    // 查询结果为已取号
                    if (regChkResponse.Status == "0")
                    {
                        // 取号成功
                        //order.OrderStatus = ApptOrderExtensions.OrderStatus.取号成功.ToInt32();
                        //order.RegNo = regChkResponse.RegNo;
                        //order.SuggestBeginTime = regChkResponse.BeginTime;
                        //order.SuggestEndTime = regChkResponse.EndTime;
                        //order.Location = regChkResponse.Address;
                        //order.VisitNo = regChkResponse.VisitNo;

                        //order.FetchTime = DateTime.Now;
                        //ctx.SaveChanges();
                        using (var ctx = new HzfyWeiXinEntities())
                        {
                            var para = new SqlParameter[]
                            {
                            new SqlParameter("@OrderStatus", ApptOrderExtensions.OrderStatus.取号成功.ToInt32()),
                            new SqlParameter("@RegNo", regChkResponse.RegInfo.RegNo),
                            new SqlParameter("@SuggestBeginTime", regChkResponse.RegInfo.StartTime),
                            new SqlParameter("@SuggestEndTime", regChkResponse.RegInfo.EndTime),
                            new SqlParameter("@Location", regChkResponse.RegInfo.Address),
                            new SqlParameter("@VisitNo", regChkResponse.RegInfo.VisitNo),
                            new SqlParameter("@FetchTime", DateTime.Now),
                            new SqlParameter("@OrderId", order.Id)
                            };
                            ctx.Database.ExecuteSqlCommand("Update ApptOrder set OrderStatus= @OrderStatus," +
                                                           "RegNo = @RegNo,SuggestBeginTime=@SuggestBeginTime," +
                                                           "SuggestEndTime=@SuggestEndTime,Location=@Location,VisitNo=@VisitNo," +
                                                           "FetchTime=@FetchTime where Id=@OrderId", para);
                        }


                        // RMQ 发送用户挂号成功通知
                        var messageProducer = new UserMessageProducer();
                        messageProducer.Publish(new UserMessageMsg
                        {
                            Type = UserMessageType.挂号成功通知,
                            OrderId = order.Id
                        });

                        // RMQ 发送发货通知
                        if (order.SumFee > 0)
                        {
                            using (var ctx = new HzfyWeiXinEntities())
                            {
                                var wxuser = ctx.WxUser.FirstOrDefault(x => x.Id == order.WxUserId);
                                if (wxuser != null)
                                {
                                    WeixinPayV3Helper.DoDeliveryNotify(wxuser.OpenId, order.WxTransactionId,
                                        "AP" + order.OrderNo,
                                        ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000)/10000000)
                                            .ToString(), "1", "");
                                }
                            }
                        }

                        //#region 用于发送报到通知
                        //var convertSucceed = false;
                        //DateTime sendTime = new DateTime();
                        //DateTime deadline = new DateTime();
                        //convertSucceed = System.DateTime.TryParse(order.RegDate + " " + order.StartTime, out sendTime);
                        //if (convertSucceed)
                        //    convertSucceed = System.DateTime.TryParse(order.RegDate + " " + order.EndTime, out deadline);

                        //var isApptOrder = order.OrderType == ApptOrderExtensions.OrderType.预约.ToInt32().ToString();
                        //if (convertSucceed && isApptOrder)
                        //{
                        //    sendTime = sendTime.AddMinutes(-40); //开诊时间前40分钟
                        //    using (var ctx = new HzfyWeiXinEntities())
                        //    {
                        //        var signInNotice = new SignInNotice
                        //        {
                        //            WxUserId = order.WxUserId,
                        //            OrderNo = order.OrderNo,
                        //            DeptName = order.DeptName,
                        //            DoctorName = order.DoctorName,
                        //            RegDate = order.RegDate,
                        //            StartTime = order.StartTime,
                        //            EndTime = order.EndTime,
                        //            Status = 0,
                        //            CardNo = order.CardNo,
                        //            CreateTime = System.DateTime.Now,
                        //            IsSended = 0,
                        //            NeedSendTime = sendTime,
                        //            DeadlineToSend = deadline
                        //        };
                        //        ctx.SignInNotice.Add(signInNotice);
                        //        ctx.SaveChanges();
                        //    }
                        //}
                        //#endregion
                    }

                    // 查询结果为未取号
                    if (regChkResponse.Status == "1")
                    {
                        // 取号失败
                        //order.OrderStatus = ApptOrderExtensions.OrderStatus.取号失败.ToInt32();
                        //ctx.SaveChanges();
                        using (var _ctx = new HzfyWeiXinEntities())
                        {
                            SqlParameter[] para =
                            {
                                new SqlParameter("@OrderStatus", ApptOrderExtensions.OrderStatus.取号失败.ToInt32()),
                                new SqlParameter("@OrderId", order.Id),
                            };
                            _ctx.Database.ExecuteSqlCommand(
                                "Update ApptOrder set OrderStatus= @OrderStatus where Id=@OrderId", para);
                        }

                        if (order.OrderType == ApptOrderExtensions.OrderType.预约.ToInt32().ToString())
                        {
                        //// RMQ 取消预约 
                        //var unapptingProducer = new OrderUnapptingProducer();
                        //unapptingProducer.Publish(new OrderUnapptingMsg
                        //{
                        //    OrderType = Rmq.Center.OrderType.挂号订单,
                        //    OrderId = order.Id,
                        //    Reason = 2
                        //});

                        // RMQ 执行取消锁号操作
                        var unlockingProducer = new OrderUnlockingProducer();
                        unlockingProducer.Publish(new OrderUnlockingMsg
                        {
                            OrderType = OrderType.挂号订单,
                            OrderId = orderId
                        });
                    }

                        // RMQ 发送用户挂号失败通知
                        var msgProducer = new UserMessageProducer();
                        msgProducer.Publish(new UserMessageMsg
                        {
                            Type = UserMessageType.挂号失败通知,
                            OrderId = order.Id
                        });

                        // RMQ 执行退费操作
                        if (order.SumFee > 0)
                        {
                            var refundingProducer = new OrderRefundingPickupFailedProducer();
                            refundingProducer.Publish(new OrderRefundingPickupFailedMsg
                            {
                                OrderType = OrderType.挂号订单,
                                OrderId = order.Id
                            });
                        }
                    }
                }
            

            return new ConsumedResult
            {
                Ack = true
            };
        }



        private ConsumedResult ProcessBillOrder(int orderId, WrapperChannel channel)
        {
            using (var ctx = new HzfyWeiXinEntities())
            {

                var order = ctx.BillOrder.FirstOrDefault(x => x.Id == orderId);
                if (order == null)
                {
                    return new ConsumedResult
                    {
                        Ack = true
                    };
                }

                var request = new Request4GetPayStatus();
                request.CardNo = order.CardNo;
                request.ClinicNo = order.ClinicNo;
                request.OrderNo = order.OrderNo;

                Response4GetPayStatus response;

                try
                {
                    var httpClient = InHttpClient.GetClient();
                    var responseMsg = httpClient.PostAsJsonAsync("HisNewWs/GetPayStatus", request).Result;
                    responseMsg.EnsureSuccessStatusCode();
                    response = responseMsg.Content.ReadAsAsync<Response4GetPayStatus>().Result;
                }
                catch (Exception ex)
                {
                    Logger.ErrorFormat("调用院内查询缴费单状态Api出错,信息：{0}", JsonConvert.SerializeObject(ex));
                    return new ConsumedResult
                    {
                        Ack = false,
                        Delay = 60 * 1000
                    };
                }

                if (response.ResultCode != "0")
                {
                    // 缴费失败
                    order.OrderStatus = BillOrderExtensions.OrderStatus.缴费失败.ToInt32();
                    ctx.SaveChanges();

                    // RMQ 发起缴费失败通知
                    var messageProducer = new UserMessageProducer();
                    messageProducer.Publish(new UserMessageMsg
                    {
                        OrderId = order.Id,
                        Type = UserMessageType.缴费失败通知
                    });

                    // RMQ 发起退款
                    var refundingProducer = new OrderRefundingPickupFailedProducer();
                    refundingProducer.Publish(new OrderRefundingPickupFailedMsg
                    {
                        OrderType = OrderType.门诊缴费订单,
                        OrderId = order.Id
                    });

                    return new ConsumedResult
                    {
                        Ack = true
                    };
                }
                else
                {
                    if (response.Status == "0")
                    {
                        // 缴费成功
                        order.OrderStatus = BillOrderExtensions.OrderStatus.缴费成功.ToInt32();

                        foreach (var disWin in response.DisWinList)
                        {
                            var newBillOrderDisWin = new BillOrderDisWin
                            {
                                BillOrderId = order.Id,
                                DisWin = disWin.DisWin,
                                DisWinAdd = disWin.DisWinAdd,
                               // RcptNo = disWin.RcptNo,
                                VisitNo = disWin.VisitNo
                            };
                            ctx.BillOrderDisWin.Add(newBillOrderDisWin);
                        }

                        order.Remark = response.ResultDesc;
                        order.FetchTime = DateTime.Now;
                        ctx.SaveChanges();

                        // RMQ 发起缴费成功通知
                        var messageProducer = new UserMessageProducer();
                        messageProducer.Publish(new UserMessageMsg
                        {
                            OrderId = order.Id,
                            Type = UserMessageType.缴费成功通知
                        });
                        var wxuser = ctx.WxUser.FirstOrDefault(x => x.Id == order.WxUserId);
                        if (wxuser != null)
                        {
                            // RMQ 发送发货通知
                            //TenpayV2Helper.DoDeliverNotify(wxuser.OpenId, order.WxTransactionId,
                            //    "BL" + order.OrderNo, "1", "");
                            WeixinPayV3Helper.DoDeliveryNotify(wxuser.OpenId, order.WxTransactionId,
                            "BL" + order.OrderNo, ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000)
                                             .ToString(), "1", "");
                        }
                    }
                    if (response.Status == "1")
                    {
                        // 缴费失败
                        order.OrderStatus = BillOrderExtensions.OrderStatus.缴费失败.ToInt32();
                        ctx.SaveChanges();

                        // RMQ 发起缴费失败通知
                        var messageProducer = new UserMessageProducer();
                        messageProducer.Publish(new UserMessageMsg
                        {
                            OrderId = order.Id,
                            Type = UserMessageType.缴费失败通知
                        });

                        // RMQ 发起退款
                        var refundingProducer = new OrderRefundingPickupFailedProducer();
                        refundingProducer.Publish(new OrderRefundingPickupFailedMsg
                        {
                            OrderType = OrderType.门诊缴费订单,
                            OrderId = order.Id
                        });

                        return new ConsumedResult
                        {
                            Ack = true
                        };
                    }
                }
            }

            return new ConsumedResult
            {
                Ack = true
            };
        }

        public class OrderSummary
        {
            public string OrderNo { get; set; }
            public string OrderType { get; set; }
            public int Id { get; set; }
            public  string RegDate { get; set; }
            public string StartTime { get; set; }
            public string EndTime { get; set; }
            public string DeptName { get; set; }
            public string DoctorName { get; set; }
            public string CardNo { get; set; }

            public decimal? SumFee { get; set; }
            public long? WxUserId { get; set; }
            public string WxTransactionId { get; set; }
        }
    }
}